package com.sora.sora.security.login.controller;

import com.anji.captcha.model.common.ResponseModel;
import com.anji.captcha.model.vo.CaptchaVO;
import com.anji.captcha.service.CaptchaService;
import com.google.code.kaptcha.Producer;
import com.sora.sora.common.constant.ResultCode;
import com.sora.sora.common.exception.ApiException;
import com.sora.sora.common.model.vo.ResultVO;
import com.sora.sora.common.model.vo.AuthenticationVO;
import com.sora.sora.common.utils.ResponseResult;
import com.sora.sora.common.utils.StringUtils;
import com.sora.sora.message.service.MailService;
import com.sora.sora.security.login.model.param.LoginParam;
import com.sora.sora.security.login.model.param.RegisterParam;
import com.sora.sora.security.login.service.LoginService;
import com.sora.sora.security.login.service.RegisterService;
import io.swagger.annotations.*;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import java.awt.image.BufferedImage;
import java.io.IOException;

@Api(value = "登录模块", tags = "登录相关接口")
@RestController
public class LoginController {

    @Resource
    private RegisterService registerService;

    @Resource
    private LoginService loginService;

    @Resource
    private CaptchaService captchaService;

    @Resource
    private MailService mailService;

    @Resource
    private ResponseResult responseResult;

    @Resource
    private Producer captchaProducer;

    @Resource
    StringUtils stringUtils;

    @ApiOperation(value = "用户登录")
    @ApiResponses({
            @ApiResponse(code = 201, message = "登录成功"),
            @ApiResponse(code = 1002, message = "登录失败")
    })
    @PostMapping("/login")
    public ResultVO login(@RequestBody @Valid LoginParam param) {
        AuthenticationVO authenticationVO = loginService.login(param);
        return authenticationVO != null ? responseResult.ok(authenticationVO) : new ResultVO(ResultCode.VALIDATE_FAILED, "账号密码错误");
    }

    @ApiOperation(value = "用户注册")
    @ApiResponses({
            @ApiResponse(code = 201, message = "创建成功"),
            @ApiResponse(code = 1002, message = "注册失败")
    })
    @PostMapping("/register")
    public ResultVO register(@RequestBody @Validated(RegisterParam.Normal.class) RegisterParam param) {
        boolean flag = registerService.register(param);
        return flag ? responseResult.ok() : responseResult.faile();
    }


    @ApiOperation(value = "忘记密码时发送邮件验证码")
    @ApiImplicitParam(name = "email", value = "用户邮箱", required = true, dataType = "string", paramType = "query")
    @GetMapping("/forget")
    public ResultVO findPasswordEmail(String email, HttpServletRequest request) {
        if (!mailService.emailExist(email)) {
            return new ResultVO(ResultCode.VALIDATE_FAILED, "邮箱不存在");
        }
        HttpSession session = request.getSession();
        boolean flag = mailService.findPassword(email, session.getId());
        return flag ? responseResult.ok() : new ResultVO(ResultCode.FORBIDDEN, "接口权限过期，请重新调用图形验证码进行验证");
    }


    @ApiOperation(value = "遗忘密码的用户进行重置密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "email", value = "用户邮箱", required = true, dataType = "string", paramType = "query"),
            @ApiImplicitParam(name = "password", value = "重置的密码", required = true, dataType = "string", paramType = "query")
    })
    @PostMapping("/reset")
    public ResultVO resetPassword(String email, String password) {
        if (!stringUtils.passwordCheck(password)) {
            return new ResultVO(ResultCode.VALIDATE_FAILED, "请按格式输入密码!");
        }
        boolean flag = loginService.resetPassword(email, password);
        if (flag) {
            mailService.infoPasswordChange(email);
            return responseResult.ok();
        }
        return new ResultVO(ResultCode.FORBIDDEN, "邮箱验证码过期");
    }


    @ApiOperation(value = "获得验证码")
    @GetMapping("/register/captcha")
    public void getCaptcha(HttpServletRequest request, HttpServletResponse response) throws IOException {
        HttpSession session = request.getSession();
        response.setDateHeader("Expires", 0);
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        response.setHeader("Pragma", "no-cache");
        response.setContentType("image/jpeg");

        String text = captchaProducer.createText();
//        session.setAttribute(Constants.KAPTCHA_SESSION_KEY, text);
        if (!registerService.saveCode(session.getId(), text)) {
            throw new ApiException(ResultCode.FAILED, "请不要频繁调用该接口!");
        }
        BufferedImage image = captchaProducer.createImage(text);
        ServletOutputStream outputStream = response.getOutputStream();
        ImageIO.write(image, "jpg", outputStream);

        try {
            outputStream.flush();
        } finally {
            outputStream.close();
        }
//        return responseResult.ok();
    }

    @ApiOperation(value = "判断验证码是否正确")
    @GetMapping("/register/captcha/check")
    public ResultVO checkCode(HttpServletRequest request, String code) {
        HttpSession session = request.getSession();
        boolean flag = registerService.checkCode(session.getId(), code);
        return flag ? responseResult.ok() : new ResultVO(ResultCode.VALIDATE_FAILED, "验证码错误");
    }


    @ApiOperation(value = "向注册用户发送验证码")
    @ApiImplicitParam(name = "recipient", value = "用户邮箱地址", required = true, paramType = "query", dataType = "string")
    @ApiResponses({
            @ApiResponse(code = 201, message = "验证码创建成功"),
            @ApiResponse(code = 1002, message = "接口权限过期，请重新调用图形验证码进行验证")
    })
    @GetMapping(value = "/register/email")
    public ResultVO registerEmail(@RequestParam("recipient") String recipient, HttpServletRequest request) {
        String sessionId = request.getSession().getId();
//        boolean register = mailService.register(recipient, sessionId);
        boolean register = mailService.register(recipient);
        return register ? responseResult.ok() : new ResultVO(ResultCode.FORBIDDEN, "接口权限过期，请重新调用图形验证码进行验证");
    }
}
